﻿
using Dapper;

using HBase;
using Net.http;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection.Emit;
using System.Reflection.Metadata;
using System.Transactions;

namespace hCommand {
    /**
   *┌────────────────────────────────────────────────┐
   *│　描    述：Component                                                    
   *│　作    者：sgj                                              
   *│　版    本：1.0                                              
   *│　创建时间：2020/9/2 11:28:16                        
   *└────────────────────────────────────────────────┘
   **/
    public abstract class ChangeLocComp : GkTransaction   {
         
        virtual public bool UpdataWhLoc(IDbConnection conn, IDbTransaction trans, long id, long goodDiff) {
            CoreWhLoc loc = conn.GetById<CoreWhLoc>(id, trans);
            if (loc != null) {//非正常货位
                if (loc.maxStock == 0) {
                    return true;
                }
                List<CoreTask> inOutList = getOutInCount(conn, trans, id);
                List<long> ining = inCount(conn, trans, id, inOutList);
                List<long> outing = outCount(conn, trans, id, inOutList);
                List<long> remainding = getStore(conn, trans, id);
                foreach (CoreTask ct in inOutList) {
                    remainding.Remove(ct.stockId);
                } 
                int count =  remainding.Count + ining.Count + outing.Count;
                if (loc.maxStock < count) {
                    String e = "inout:";
                    foreach (CoreTask ct in inOutList) {
                        e += ct.id + ",";
                    }
                    e += "ining:";
                    foreach (long inid in ining)
                    {
                        e += inid + ",";
                    }
                    e += "outing:";
                    foreach (long outid in outing)
                    {
                        e += outid + ",";
                    }
                    e += "remainding:";
                    foreach (long ramain in remainding)
                    {
                        e += ramain + ",";
                    }
                    throw new Exception(String.Format("[{0}]货位存放货位过多[{1}][{2}][{3}]", id, count, ining.Count, outing.Count)+e);
                }
                if (count == 0) {
                    goodDiff = 0;
                }
                if (loc.countStock == count &&  loc.goodsDiff == goodDiff && loc.countIn == ining.Count &&  outing.Count == loc.countOut &&inOutList.Count == loc.countOutin) {
                    return true;
                }

                string sql2 = @"update core_wh_loc set Count_stock=@count,goods_diff=@goodDiff,Count_out=@outing ,count_in=@ining ,count_outin=@inOut  where id=@id";
                conn.Execute(sql2, new { id, count, goodDiff, outing = outing.Count, ining = ining.Count, inOut = inOutList.Count }, trans);
                CoreWhGroup group = updateMoveGroup(conn, trans, loc.areaId, loc.moveGroup, loc.craneId);
                saveCoreWhGroupStat(conn, trans, group, loc.goodsDiff);
            } else {
                CoreWhGroup group = conn.GetById<CoreWhGroup>(id, trans);
                if (group != null) {
                    updateMoveGroup(conn, trans, group.areaId, group.locGroup, 0);
                    saveCoreWhGroupStat(conn, trans, group, goodDiff);
                }
            }
            return true;
        }
        int pkMoveFinsh(IDbConnection conn, IDbTransaction trans, long stn) {
            String pkedSql = "SELECT count( distinct s.id) FROM core_stock s join  core_task t on s.id=t.stock_Id join core_task_param p on t.id=p.task_Id  WHERE s.loc_Id=t.src and t.src=t.des and p.status>{0} and p.status<{1}  and s.loc_id=@loc  ";
            pkedSql = HUtil.formatInt(pkedSql, CoreTaskParamStatus.新建, CoreTaskParamStatus.执行完成);
            int pked = conn.QueryUnique<int>(pkedSql, new { loc = stn }, trans);
            return pked;

        }

        List<CoreTask> getOutInCount(IDbConnection conn, IDbTransaction trans, long stn) {
            return new List<CoreTask>();
            String outInCountSql = " SELECT stock_id,id FROM  Core_task where src=des  and status = {0}  and src = @stn";
            outInCountSql = HUtil.formatInt(outInCountSql, CoreTaskStatus.执行中 );
            List<CoreTask> outInCount = conn.Query<CoreTask>(outInCountSql, new { stn }, trans).ToList();
            return outInCount;
        }

         List<long> inCount(IDbConnection conn, IDbTransaction trans, long stn, List<CoreTask> inOutList) {
            String inCountSql = @"SELECT task_Id FROM Core_task_param where des=@stn and status >= {0} and status <{1} and type = {2} ";


            inCountSql = HUtil.formatInt(inCountSql, CoreTaskParamStatus.新建, CoreTaskParamStatus.执行完成, TaskParamType.托盘搬运);
            List<long> inCount = conn.Query<long>(inCountSql, new { stn }, trans).AsList();

            foreach (CoreTask ct in inOutList) {
                inCount.Remove(ct.id);
            }
            return inCount;
        }

         List<long> outCount(IDbConnection conn, IDbTransaction trans, long stn, List<CoreTask> inOutList) {
            String outCountSql = @"SELECT task_Id FROM Core_task_param where src=@stn and status >= {0} and status <{1} and type = {2}";
            outCountSql = HUtil.formatInt(outCountSql, CoreTaskParamStatus.新建, CoreTaskParamStatus.执行完成, TaskParamType.托盘搬运);


            List<long> outCount = conn.Query<long>(outCountSql, new { stn }, trans).ToList();

            foreach (CoreTask ct in inOutList) {
                outCount.Remove(ct.id);
            }
            return outCount;
        }


         List<long> getStore(IDbConnection conn, IDbTransaction trans, long stn) {
            string sql = @"select id from core_stock where  loc_Id=@locId and (status =" + (int)StockStatus.库存+")";//货出库中的货位，入库位置不在货位
            List<long> remaindCount = conn.Query<long>(sql, new { locId = stn }, trans).ToList();
            string sql2 = @"select s.id from core_stock s  where not EXISTS (select 1 from core_task t  where  s.id=t.stock_id and t.status=2 ) and s.loc_Id=@locId and   s.status =" + (int)StockStatus.盘库中 + "";//货出库中的货位，入库位置不在货位
            List<long> remaindCount2 = conn.Query<long>(sql2, new { locId = stn }, trans).ToList();
            remaindCount.AddRange(remaindCount2);
            return remaindCount;
        }

        

         public void saveCoreWhGroupStat(IDbConnection conn, IDbTransaction tran, CoreWhGroup group, long deff) {
            if (!BaseConfig.islocGroup) {
                return;
            }
            long areaId = group.areaId;
            int groupId = group.locGroup;
            var param = new { areaId, groupId, deff };

            string sql = "select * from core_wh_group_stat where  group_Id =@groupId and  area_Id =@areaId and diff_Key=@deff ";

            CoreWhGroupStat diff = conn.QueryUnique<CoreWhGroupStat>(sql, param, tran);
            //到货位的数量
            String countSql = "SELECT sum(Count_stock) FROM core_wh_loc  where move_Group = @groupId and area_Id = @areaId and goods_Diff = @deff";
            int cont = conn.QueryUnique<int>(countSql, param, tran);
            //去区域的数量
            String iningSql = "SELECT count(*) FROM core_stock s join core_task t on s.id=t.stock_Id join core_task_param p on t.id=p.task_id " +
                " where s.deep_diff=@deff and p.des=@des and p.status >= {0} and  p.status <{1}";

            iningSql = HUtil.formatInt(iningSql, CoreTaskParamStatus.新建, CoreTaskParamStatus.执行完成);
            cont += conn.QueryUnique<int>(iningSql, new { deff, des = group.id }, tran);

            if (diff == null) {
                diff = new CoreWhGroupStat();
              
                diff.areaId = areaId;
                diff.groupId = groupId;
                diff.diffKey = deff;
                diff.countStock = cont;
                conn.InsertNoNull(diff, tran);
            } else {
                string updateSql = "update core_wh_group_stat set count_stock=@countStock  where id=@id";
                diff.countStock = cont;
                conn.Execute(updateSql, diff, tran);
            }
        }


         public CoreWhGroup updateMoveGroup(IDbConnection conn, IDbTransaction tran, long areaId, int moveGroup, int craneId) {
            if (!BaseConfig.islocGroup) {
                return null;
            }
            CoreWhGroup group = getCoreWhGroup(conn, tran, areaId, moveGroup);
            CoreWhGroup data = statAreaGroupData(conn, tran, areaId, moveGroup);
            group.maxStock = data.maxStock;
            group.countStock = data.countStock;
            group.countIn = data.countIn;
            group.countOut = data.countOut;
            group.countOutin = data.countOutin;
            if (group.id == 0) {
                if (craneId > 0) {
                    group.id = I18nConfig.getGroupId(conn, tran, moveGroup);
                    group.craneId = (byte)craneId;
                    conn.Insert(group, tran);
                }

            } else {
                int begin = (int)CoreTaskParamStatus.待执行;
                int end = (int)CoreTaskParamStatus.执行结束;
                String sql = @"  SELECT count(*) FROM core_task_param  where des = @des  and (type<>9 && status between " + begin + "  and " + end + ")";
                group.countIning = conn.QueryUnique<int>(sql, new { des = group.id }, tran);
                conn.Update(group, tran);
            }
            return group;
        }



         CoreWhGroup statAreaGroupData(IDbConnection conn, IDbTransaction tran, long areaId, long moveGroup) {
            String sql = @" select sum(max_stock) max_Stock,sum(count_stock) count_Stock,
                        sum(Count_out) count_out,sum(count_in) count_In,sum(count_outin) count_outin
                            from core_wh_loc 
                            where area_Id = @areaId and move_group=@moveGroup  and Active_Status in (0,1,2)";
            CoreWhGroup res = conn.QueryUnique<CoreWhGroup>(sql, new { areaId, moveGroup }, tran);
            return res;
        }
         CoreWhGroup getCoreWhGroup(IDbConnection conn, IDbTransaction tran, long areaId, int moveGroup) {
            string sql1 = "select * from   Core_Wh_Group where area_Id=@areaId and loc_group=@moveGroup";
            CoreWhGroup group = conn.QueryUnique<CoreWhGroup>(sql1, new { areaId, moveGroup }, tran);
            if (group == null) {
                group = new CoreWhGroup();
                group.areaId = areaId;
                group.locGroup = moveGroup;
            }
            return group;
        }
    }
}

